/*
 * Copyright (c) 2020. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
 * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
 * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
 * Vestibulum commodo. Ut rhoncus gravida arcu.
 */

package cn.afterturn.easypoi.word.entity.bookmark;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.export.ExcelExportService;
import cn.afterturn.easypoi.word.bookmarkutil.BooknameUtil;
import cn.afterturn.easypoi.word.entity.bookmark.ExportExecel.Constant;
import cn.afterturn.easypoi.word.entity.bookmark.ExportExecel.NormalParagraph;
import cn.afterturn.easypoi.word.entity.bookmark.ExportExecel.TablePara;
import cn.afterturn.easypoi.word.entity.handleWordEntity.HandleWordCellNull;
import cn.afterturn.easypoi.word.vo.WordPage;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.File;
import java.io.FileOutputStream;
import java.util.*;
import java.util.stream.Collectors;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class WordEntityPrint {
    public static void print(WordEntityVO wordEntityVO){
        System.out.println("对word中所有的空的内容进行过滤Begin：**********************************-----------"+"\r\n");
        HandleWordCellNull handleWordCellNull=new HandleWordCellNull();
        wordEntityVO =handleWordCellNull.handle(wordEntityVO);
        System.out.println("对word中所有的空的内容进行过滤End：**********************************--------------"+"\r\n");
        System.out.println("对word中所有的para的进行打印："+"\r\n");
        paraPrint(wordEntityVO.getParagraphEntityVOS());
        System.out.println("----------------------------------------------------------------"+"\r\n");
        System.out.println("对word中所有的Header中Paragraph的进行打印："+"\r\n");
        wordEntityVO.getHeaderEntityVOS().forEach(headerEntity -> {
                paraPrint(headerEntity.getParagraphEntityVOS());
            });
        System.out.println("----------------------------------------------------------------"+"\r\n");
        System.out.println("对word中所有的Footer中Paragraph的进行打印："+"\r\n");
        wordEntityVO.getFootEntityVOS().forEach(footEntity -> {
            paraPrint(footEntity.getParagraphEntityVOS());
        });

        System.out.println("----------------------------------------------------------------"+"\r\n");
      //  System.out.println("对word中所有的Table中Paragraph的进行打印："+"\r\n");
        /*wordEntityVO.getTableEntityVOS().forEach(tableEntity -> {
            tableEntity.getRowEntityVOS().forEach(rowEntity -> {
                rowEntity.getCellEntityVOS().forEach(cellEntity -> {
                    paraPrint(cellEntity.getParagraphEntityVOS());
                });
            });
        });*/

    }
    private static  void paraPrint(Set<ParagraphEntityVO> paragraphEntities){
        //对ParagraphSet进行排序
        TreeSet<ParagraphEntityVO> treeSet = new TreeSet<>(new Comparator<ParagraphEntityVO>() {
            @Override
            public int compare(ParagraphEntityVO o1, ParagraphEntityVO o2) {
                return  o1.getParaSequence()-o2.getParaSequence();   //改写排序规则，升序排序
            }
        });
        paragraphEntities.forEach(para->{
            treeSet.add(para);
        });

        treeSet.forEach(para->{
            System.out.println("    para.getParaText():"+para.getParaText()+"\r\n");
            para.getBookMarkEntityVOS().forEach(bookmark->{
                System.out.println("         bookmark.getBookmarkname():"+bookmark.getBookmarkname()+"\r\n");
            });
        });

    }
    private static void setNormalParagraph(NormalParagraph normalParagraph, WordEntityVO wordEntityVO, ParagraphEntityVO paragraphEntityVO, BookMarkEntityVO bookMarkEntityVO){
        normalParagraph.setFileId(wordEntityVO.getId());
        normalParagraph.setFileName(wordEntityVO.getFilename());
        normalParagraph.setParagraphText(paragraphEntityVO.getParaText());
        normalParagraph.setBookMarkName(bookMarkEntityVO.getBookmarkname());
        normalParagraph.setBookMarkFromHFPC(Constant.Paragraph);
        normalParagraph.setParasequence(paragraphEntityVO.getParaSequence());
        normalParagraph.setBooksequence(bookMarkEntityVO.getBookmarkNoOfPara());
        normalParagraph.setParagraphText(paragraphEntityVO.getParaText());
        String content= bookMarkEntityVO.getBookmarkname();
        //normalParagraph.setBookmarkType(BookMarkType(content));
        normalParagraph.setBookmarkType(BooknameUtil.BookMarkType(content));
        /*if(content.contains(Constant.NOW)||
                content.contains(PoiElUtil.LENGTH)
                ||content.contains(Constant.PICTURE)||content.contains(Constant.THREECOMPUTEASK)){
            normalParagraph.setBookmarkType(Constant.ComputedbookMark);
        }else {
            normalParagraph.setBookmarkType(Constant.NormalbookMark);
        }*/
    }
    private static Set<NormalParagraph> wordEntityConvertParagraphFromParagraph(WordEntityVO wordEntityVO){
        Set<NormalParagraph> normalParagraphs=new HashSet<>();
        wordEntityVO.getParagraphEntityVOS().forEach(paragraphEntity -> {
            if(paragraphEntity.getBookMarkEntityVOS()!=null) {
                paragraphEntity.getBookMarkEntityVOS().forEach(bookMarkEntity -> {

                    NormalParagraph normalParagraph=new NormalParagraph();
                    normalParagraphs.add(normalParagraph);
                    setNormalParagraph(normalParagraph, wordEntityVO,paragraphEntity,bookMarkEntity);

                    normalParagraph.setBookMarkFromHFPC(Constant.Paragraph);

                });
                //}
            }}
        );
        return normalParagraphs;
    }
    private static Set<NormalParagraph> wordEntityConvertParagrapphFromHeaderandFoot(WordEntityVO wordEntityVO){
        Set<NormalParagraph> normalParagraphs=new HashSet<>();
        wordEntityVO.getHeaderEntityVOS().forEach(headerEntity -> {
            headerEntity.getParagraphEntityVOS().forEach(paragraphEntity -> {
                if(paragraphEntity.getBookMarkEntityVOS()!=null) {
                    paragraphEntity.getBookMarkEntityVOS().forEach(bookMarkEntity -> {
                        NormalParagraph normalParagraph = new NormalParagraph();
                        normalParagraphs.add(normalParagraph);
                        setNormalParagraph(normalParagraph, wordEntityVO,paragraphEntity,bookMarkEntity);

                        normalParagraph.setBookMarkFromHFPC(Constant.Header);
                    });
                }});
        });

        wordEntityVO.getFootEntityVOS().forEach(footEntity -> {
            footEntity.getParagraphEntityVOS().forEach(paragraphEntity -> {
                if(paragraphEntity.getBookMarkEntityVOS()!=null) {
                    paragraphEntity.getBookMarkEntityVOS().forEach(bookMarkEntity -> {
                        NormalParagraph normalParagraph = new NormalParagraph();
                        normalParagraphs.add(normalParagraph);
                        setNormalParagraph(normalParagraph, wordEntityVO,paragraphEntity,bookMarkEntity);
                        normalParagraph.setBookMarkFromHFPC(Constant.Foot);
                    });
                }});
        });
        return  normalParagraphs;
    }
    private static Set<TablePara> wordEntityConvertTableParaFromTable(WordEntityVO wordEntityVO){
        Set<TablePara> tableParas=new HashSet<>();
        wordEntityVO.getTableEntityVOS().forEach(tableEntity -> {
            if(tableEntity.getRowEntityVOS()!=null){
                tableEntity.getRowEntityVOS().forEach(rowEntity -> {
                    if(rowEntity.getCellEntityVOS()!=null){
                        rowEntity.getCellEntityVOS().forEach(cellEntity -> {
                            if(cellEntity.getParagraphEntityVOS()!=null){
                                cellEntity.getParagraphEntityVOS().forEach(paragraphEntity -> {
                                    if(paragraphEntity.getBookMarkEntityVOS()!=null){
                                        paragraphEntity.getBookMarkEntityVOS().forEach(bookMarkEntity -> {
                                            TablePara tablePara=new TablePara();
                                            tablePara.setFileId(wordEntityVO.getId());
                                            tablePara.setFileName(wordEntityVO.getFilename());
                                            tablePara.setBookMarkFromHFPC(Constant.Cell);
                                            tablePara.setTableNo(String.valueOf(tableEntity.getTableSequence()));
                                            tablePara.setTableText(tableEntity.getTableText());
                                            tablePara.setTableHashNo(tableEntity.getTableHashcode());
                                            tablePara.setRowno(String.valueOf(rowEntity.getRowIndex()));

                                            tablePara.setRowFirstColumnText(rowEntity.getRowFirstColumnText());
                                            tablePara.setCellno(String.valueOf(cellEntity.getCellVertical()));
                                            tablePara.setCellText(cellEntity.getCellText());
                                            tablePara.setParasequence(paragraphEntity.getParaSequence());
                                            tablePara.setParagraphText(paragraphEntity.getParaText());
                                            tablePara.setBooksequence(bookMarkEntity.getBookmarkNoOfPara());
                                            tablePara.setBookMarkName(bookMarkEntity.getBookmarkname());
                                            String content=bookMarkEntity.getBookmarkname();
                                            //正常字段，计算字段 ，未来可能进一步调整
                                            tablePara.setBookmarkType(BooknameUtil.BookMarkType(content));
                                            /*if(content.contains(Constant.NOW)||
                                                    content.contains(PoiElUtil.LENGTH)
                                                    ||content.contains(Constant.PICTURE)||content.contains(Constant.THREECOMPUTEASK)){
                                                tablePara.setBookmarkType(Constant.ComputedbookMark);
                                            }else {
                                                tablePara.setBookmarkType(Constant.NormalbookMark);
                                            }*/
                                            tableParas.add(tablePara);
                                        });
                                    }});
                            }});
                    }});
            }});
        return tableParas;
    }


    public static WordPage exportToWordPage(WordEntityVO wordEntityVO) {
        List<Object> objects = new ArrayList<>();
        Set<NormalParagraph> normalParagraphs = new HashSet<>();
        //将wordEntity的段落，转换为Set<NormalParagraph>
        Set<NormalParagraph> normalfromParagraphs = wordEntityConvertParagraphFromParagraph(wordEntityVO);
        normalParagraphs.addAll(normalfromParagraphs);
        normalParagraphs.addAll(wordEntityConvertParagrapphFromHeaderandFoot(wordEntityVO));
        //根据这个导出的内容，在填写的时候，bookmark的名称就不能重复。
        //但是在table中，就可以与Bookmark重复
        //导出Table
        Set<TablePara> tableParas = new HashSet<>();
        tableParas.addAll(wordEntityConvertTableParaFromTable(wordEntityVO));
        normalParagraphs.forEach(normalParagraph -> {
            System.out.println(normalParagraph.toString() + "\r\n");
        });
        System.out.println("******************************************************************" + "\r\n");
        tableParas.forEach(tablePara -> {
            System.out.println(tablePara.toString() + "\r\n");
        });
        //转为List
        List<NormalParagraph> normalParagraphs1 = new ArrayList<>();
        List<TablePara> tableParas1 = new ArrayList<>();
        normalParagraphs.forEach(n -> {
            normalParagraphs1.add(n);
        });
        tableParas.forEach(y -> {
            tableParas1.add(y);
        });

        //对这个List进行排序，便于输出校对
        /*normalParagraphs1.stream().sorted(Comparator.comparing(NormalParagraph::getBookMarkFromHFPC)
                .thenComparing(NormalParagraph::getParasequence));*/
        //特别需要注意，排序之后，对产生的新的List是生效的。对于原来的List没有效。所以要采用最后的ToList的方法
        //另外。Set无法进行排序。需要转为List进行排序

        List<NormalParagraph> normalParagraphList= normalParagraphs1.stream().sorted(Comparator.comparing(NormalParagraph::getBookMarkFromHFPC)
                .thenComparing(NormalParagraph::getParasequence)).collect(Collectors.toList());
        for(int i=0;i<normalParagraphList.size();i++)
            System.out.println("获取的书签顺序是:"+normalParagraphList.get(i).toString());

        List<TablePara> afterSeqTableParaList= tableParas1.stream().sorted(Comparator.comparing(TablePara::getTableNo)
                .thenComparing(TablePara::getRowno)
                .thenComparing(TablePara::getCellno)
                .thenComparing(TablePara::getParasequence)
                .thenComparing(TablePara::getBooksequence))
                .collect(Collectors.toList());
        WordPage wordPage = new WordPage();
        wordPage.setNormalParagraphList(normalParagraphList);//给出排序后的集合
        wordPage.setTableParaList(afterSeqTableParaList);
        jsonPrint(wordPage);
        return wordPage;
    }
    private List<NormalParagraph> NormalSort(List<NormalParagraph> normalParagraphs1){
        List<NormalParagraph> normalParagraphList= normalParagraphs1.stream().sorted(Comparator.comparing(NormalParagraph::getBookMarkFromHFPC)
                .thenComparing(NormalParagraph::getParasequence)).collect(Collectors.toList());
        return  normalParagraphList;
    }
    private List<TablePara> TableParaSort(List<TablePara> tableParas1){
        List<TablePara> afterSeqTableParaList= tableParas1.stream().sorted(Comparator.comparing(TablePara::getTableNo)
                .thenComparing(TablePara::getRowno)
                .thenComparing(TablePara::getCellno)
                .thenComparing(TablePara::getParasequence)
                .thenComparing(TablePara::getBooksequence))
                .collect(Collectors.toList());
        return afterSeqTableParaList;
    }
    private static void jsonPrint(WordPage wordPage){
        String jsonData = JSONObject.toJSONString(wordPage,SerializerFeature.WriteMapNullValue);
        System.out.println("这个是Json的前后端的接口参数格式:\r\n");
        System.out.println(jsonData);
        System.out.println("Json格式打印结束");
    }
    public static WordPage exportFile(WordPage wordPage,String exportVerfyFilepath) {
        List<NormalParagraph> normalParagraphs1=wordPage.getNormalParagraphList();
        List<TablePara> tableParas1=wordPage.getTableParaList();

        List<NormalParagraph> backupNormalPara=new ArrayList<>();
        List<TablePara> backuptableParasSet=new ArrayList<>();
        normalParagraphs1.forEach(normalParagraph -> {
            backupNormalPara.add(normalParagraph);
        });


        tableParas1.forEach(tablePara -> {
            backuptableParasSet.add(tablePara);
        });
        WordPage wordPage1=new WordPage();
        wordPage1.setNormalParagraphList(backupNormalPara);
        wordPage1.setTableParaList(backuptableParasSet);

        exportFile(normalParagraphs1,tableParas1,exportVerfyFilepath);
        return wordPage1;
    }

    public static WordPage handWordPageStandard(WordPage wordPage) {
        List<NormalParagraph> normalParagraphs2=handleNormalParagraph(wordPage.getNormalParagraphList());
        //重新排序
        List<NormalParagraph> normalParagraphList= normalParagraphs2.stream().sorted(Comparator.comparing(NormalParagraph::getBookMarkFromHFPC)
                .thenComparing(NormalParagraph::getParasequence)).collect(Collectors.toList());

        wordPage.setNormalParagraphList(normalParagraphList);
        List<TablePara> tableParas2=handleTabeParagraph(wordPage.getTableParaList());
        //重新排序

        List<TablePara> afterSeqTableParaList= tableParas2.stream().sorted(Comparator.comparing(TablePara::getTableNo)
                .thenComparing(TablePara::getRowno)
                .thenComparing(TablePara::getCellno)
                .thenComparing(TablePara::getParasequence)
                .thenComparing(TablePara::getBooksequence))
                .collect(Collectors.toList());

        wordPage.setTableParaList(afterSeqTableParaList);
        return wordPage;
    }


    public static List<Object> exportToExcelEntity(WordEntityVO wordEntityVO, String exportVerfyFilepath, String exportImportFilepath){
        List<Object> objects=new ArrayList<>();
        Set<NormalParagraph> normalParagraphs=new HashSet<>();
        //将wordEntity的段落，转换为Set<NormalParagraph>
        Set<NormalParagraph> normalfromParagraphs=wordEntityConvertParagraphFromParagraph(wordEntityVO);
        normalParagraphs.addAll(normalfromParagraphs);
        normalParagraphs.addAll(wordEntityConvertParagrapphFromHeaderandFoot(wordEntityVO));
        //根据这个导出的内容，在填写的时候，bookmark的名称就不能重复。
        //但是在table中，就可以与Bookmark重复
        //导出Table
        Set<TablePara> tableParas=new HashSet<>();
        tableParas.addAll(wordEntityConvertTableParaFromTable(wordEntityVO));
        normalParagraphs.forEach(normalParagraph -> {
            System.out.println(normalParagraph.toString()+"\r\n");
        });
        System.out.println("******************************************************************"+"\r\n");
        tableParas.forEach(tablePara -> {
            System.out.println(tablePara.toString()+"\r\n");
        });
        //转为List
        List<NormalParagraph> normalParagraphs1=new ArrayList<>();
        List<TablePara> tableParas1=new ArrayList<>();
        normalParagraphs.forEach(n->{
            normalParagraphs1.add(n);
        });
        tableParas.forEach(y->{
            tableParas1.add(y);
        });
        WordPage wordPage=new WordPage();
        wordPage.setNormalParagraphList(normalParagraphs1);
        wordPage.setTableParaList(tableParas1);

        String filePath=System.getProperty("user.dir");
        String relativefilePath=filePath+"\\src\\main\\java\\cn\\afterturn\\easypoi\\word\\files\\";

        List<NormalParagraph> backupNormalPara=new ArrayList<>();
        List<TablePara> backuptableParasSet=new ArrayList<>();
        normalParagraphs.forEach(normalParagraph -> {
            backupNormalPara.add(normalParagraph);
        });
        //对这个List进行排序，便于输出校对
        normalParagraphs.stream().sorted(Comparator.comparing(NormalParagraph::getBookMarkFromHFPC)
        .thenComparing(NormalParagraph::getParasequence));
        //https://www.jianshu.com/p/f38aeb894e9c java stream 排序
        tableParas.forEach(tablePara -> {
            backuptableParasSet.add(tablePara);
        });
        tableParas.stream().sorted(Comparator.comparing(TablePara::getTableNo)
                .thenComparing(TablePara::getRowno)
                .thenComparing(TablePara::getCellno)
                .thenComparing(TablePara::getBooksequence));
        exportFile(normalParagraphs1,tableParas1,exportVerfyFilepath);
        //处理后要进行填写的表格
       // String exportImportFilepath=relativefilePath+"after处理后填写的模板.xlsx";
        List<NormalParagraph> normalParagraphs2=handleNormalParagraph(backupNormalPara);
        List<TablePara> tableParas2=handleTabeParagraph(backuptableParasSet);
        exportFile(normalParagraphs2,tableParas2,exportImportFilepath);
return objects;
    }

    private static void exportFile(List<NormalParagraph> normalParagraphs,List<TablePara> tableParas,String filepath){
        try{
            //导出Excel,多个sheet
            ExportParams params = new ExportParams("BookMark", "Normal", ExcelType.XSSF);
            Workbook workbook = ExcelExportUtil.exportExcel(params, NormalParagraph.class, normalParagraphs);
            ExportParams paramsTable = new ExportParams("BookMark", "Table", ExcelType.XSSF);
            //Workbook workbook = ExcelExportUtil.exportExcel(params,NormalParagraph.class, normalParagraphs);
            new ExcelExportService().createSheet(workbook, paramsTable, TablePara.class, tableParas);

            //这个目录好像没有用，会自己引用filepath
            File savefile = new File("D:/home/excel/");
            if (!savefile.exists()) {
                savefile.mkdirs();
            }
            FileOutputStream fos = new FileOutputStream(filepath);
            workbook.write(fos);
            fos.close();
        }
        catch (Exception ex){
            System.out.println(ex.toString());
        }
    }
    //针对正常的para，删除重复的
    //针对表格，删除fe:
    private static List<NormalParagraph> handleNormalParagraph(List<NormalParagraph> normalParagraphs){
        Map<String,List<NormalParagraph>> map= normalParagraphs.stream()
                .collect(Collectors.groupingBy(NormalParagraph::getBookMarkName));
        //对这个map中，重复的只保留一个
        List<NormalParagraph> tempSet=new ArrayList<>();
        map.forEach((k,v)->{
            tempSet.add(v.get(0));
        });

    return tempSet;

    }
    //针对正常的para，删除重复的
    //针对表格，删除fe:
    private static List<TablePara> handleTabeParagraph(List<TablePara> tableParas){

        //List<TablePara> tempSet=new ArrayList<>();
        Iterator<TablePara> iterator=tableParas.iterator();
        while (iterator.hasNext()){
            TablePara tablePara=iterator.next();
            if(tablePara.getBookMarkName().contains("{{fe:}}")){
                iterator.remove();
            }
            //这个地方没有删除掉
          //  tempSet.add(tablePara);
        }
        return tableParas;
    }
}
